<?php

/**
 * Description of WSActiveForm
 *
 * @author Thomas Vo
 */
class BRActiveForm extends CActiveForm
{
    public function init()
    {
        $action = $this->action ? $this->action : Yii::app()->createUrl(Yii::app()->controller->id.'/'.Yii::app()->controller->action->id);

        if(!isset($this->htmlOptions['id']))
			$this->htmlOptions['id']=$this->id;
		if($this->stateful)
			echo CHtml::statefulForm($action, $this->method, $this->htmlOptions);
		else
			echo CHtml::beginForm($action, $this->method, $this->htmlOptions);
    }
    /**
     * if groupName is false(by default), generate rows of all fields specified in $formModel->attributeGroups();
     * if groupName is specified, generate rows of only the fields of the group
     * @param WSFormModel $formModel 
     */
    public function generateForm($formModel, $attributeGroupName = false, $errorDisplay = true, $return = false)
    {
        $result = '';     
        if($attributeGroupName !== false && $attributeGroupName !== null)
        {
            $attributeGroup = $formModel->getAttributeGroup($attributeGroupName);
            $attributeNames = $attributeGroup->getAttributeNames();
            //print group name
            if($attributeGroup->getName())
                $result .= '<div class="groupname">'.$attributeGroup->getName().'</div>';

            //iterate through attributeNames to generate input fields
            foreach($attributeNames as $attributeName)
                $result .= $this->generateFormRow($formModel, $attributeName, $attributeGroup, $errorDisplay, true);
            
        }
        else
        {
            foreach($formModel->getAttributeGroupNames() as $attributeGroupName)
                $result .= $this->generateForm($formModel, $attributeGroupName, $errorDisplay, true);
            
        }
        
        if($return)
            return $result;
        else 
            echo $result;
        
        
    }
    
    /**
     * generate a row of label, input, and error displaying area
     * @param WSFormModel $formModel
     * @param string $attributeName
     * @param attributeGroup the attribute group that this form belongs to, defaults to null
     * @param boolean $errorDisplay whether to generate the error displaying area
     * @param boolean $return whether to return or echo the html
     * @return string 
     */
    public function generateFormRow($formModel, $attributeName, $attributeGroup = null, $errorDisplay = true, $return = false)
    {
        $result  = ''; 
        $result .= '<div class="row" id="'.get_class($formModel).'_'.$attributeName.'_row">';
        $result .= $this->labelEx($formModel,$attributeName);
        $result .= $this->generateInput($formModel, $attributeName, $attributeGroup, true);
        $result .= $errorDisplay ? $this->error($formModel,$attributeName) : null; 
        $result .= '</div>';
        
        if($return)
            return $result;
        else 
            echo $result;
    }
    
    /**
     * only generate the input of the attribute. 
     * @param WSFormModel $formModel
     * @param string $attributeName
     * @param boolean $return
     * @return string 
     */
    public function generateInput($formModel, $attributeName, $attributeGroup = null, $return = false)
    {
        if(!$formModel->hasAttribute($attributeName))
            throw new WSException('Model "'.get_class($formModel).'" does not have attribute '.$attributeName.'.');
        $result = '';
        // get the formSettings for the current attribute, if nothing
        // is returned then generate a textfield by default
        $settings = $attributeGroup === null ? 
            $formModel->getFormSettings($attributeName) 
            : 
            $attributeGroup->getFormSettings($attributeName);
        
        // if the settings are not specified then generate a textfield by default
        $result .= $settings ? 
            call_user_method_array($settings[0], $this, array_merge(array($formModel, $attributeName), array_slice($settings, 1)))
            :
            $this->textField($formModel,$attributeName);

        
        if($return)
            return $result;
        else 
            echo $result;
    }
    
    
    
    ///////FORM COMMAND SYSTEM///////
    
    /**
     * Generate a hidden field to represent a command that this form send to the controller.
     * You can user getCommands() to get a list of commands available.
     * Or you can use getCommand() to get the value of a specific command.
     * @param string $name
     * @param mixed $value
     * @param boolean $return
     * @return string 
     */
    public function generateFormCommand($name, $value = null, $return = false)
    {
        $result = CHtml::hiddenField($this->id.'[commands]'.'['.$name.']', $value);
        
        if($return)
            return $result;
        else 
            echo $result;
    }
    
    
    
    /**
     * Simply generate a form with a single submit button
     * @param mixed  $controller
     * @param string $categoryId
     * @param string $buttonText
     * @param string $commandName
     * @param string $commandValue
     * @param array $buttonHtmlOptions defaults to array()
     * @param array $formHtmlOptions defaults to array()
     * @param boolean $return defaults to false
     */
    public static function generateFormCommandButton($buttonText, $categoryId, $commandName, $commandValue, $buttonHtmlOptions=array(), $formOptions=array(), $return = false)
    {
        $controller        = Yii::app()->controller;
        $formOptions['id'] = $categoryId;
        
        if(!isset($formOptions['htmlOptions']))
        {
            $formOptions['htmlOptions'] = array(
                'style' => 'display: inline',
            );
        }
        ob_start();
        $controller->beginWidget('WSActiveForm', $formOptions); 
            $buttonHtmlOptions['name']    = $categoryId.'[commands]'.'['.$commandName.']';
            $buttonHtmlOptions['value']   = $commandValue;
            $buttonHtmlOptions['type']    = 'submit';

            echo CHtml::tag('button', $buttonHtmlOptions, $buttonText);
        $controller->endWidget();
        
        $html = ob_get_contents();
        ob_end_clean();
        
        if($return)
            return $html;
        else
            echo $html;
    }
    
    
    /**
     * Simply generate a form with a single submit button
     * @param string $src
     * @param string $categoryId
     * @param string $commandName
     * @param string $commandValue
     * @param array $buttonHtmlOptions defaults to array()
     * @param array $formHtmlOptions defaults to array()
     * @param boolean $return defaults to false
     */
    public static function generateFormCommandImageButton($src, $categoryId , $commandName, $commandValue, $buttonHtmlOptions=array(), $formHtmlOptions=array(), $return = false)
    {
        $controller        = Yii::app()->controller;
        $formHtmlOptions['id'] = $categoryId;
        
        if(!isset($formHtmlOptions['htmlOptions']))
        {
            $formHtmlOptions['htmlOptions'] = array(
                'style' => 'display: inline',
            );
        }
        ob_start();
        $formWidget = $controller->beginWidget('WSActiveForm', $formHtmlOptions); 
            $formWidget->generateFormCommand($commandName,$commandValue);
            echo CHtml::imageButton($src, $buttonHtmlOptions);
        $controller->endWidget();
        
        $html = ob_get_contents();
        ob_end_clean();
        
        if($return)
            return $html;
        else
            echo $html;
        
    }
    
    
    public static function getCommands($categoryId)
    {
        return isset($_POST[$categoryId]['commands']) ? $_POST[$categoryId]['commands'] : null;
    }
    
    public static function getCommand($categoryId, $commandName)
    {
        return isset($_POST[$categoryId]['commands'][$commandName]) ? $_POST[$categoryId]['commands'][$commandName] : null;
    }
    
    /**
     * check if ajax is on for the specified form
     * @param string $formId the id of the form being evaluated
     * @return boolean 
     */
    public static function isAjaxOn($formId)
    {
        return isset($_POST['ajax']) && $_POST['ajax'] === $formId;
    }
    
    /**
     * 
     * @param string $formClassName
     * @return array|boolean an array of attributes => values on success, false on failure
     */
    public static function getSubmittedFormAttributes($formClassName)
    {
        return isset($_POST[$formClassName]) ? $_POST[$formClassName] : false;
    }
    
    /**
     * Create a simple yes no radio button list. 
     * The default configurations are shown here in the code below. </br>
     * <code>
     * $labelOptions = array(</br>
     * &nbsp&nbsp&nbsp&nbsp'style' => 'display:inline',</br>
     * &nbsp&nbsp);</br>
     * $data = array('1'=>'Yes','0'=>'No');</br>
     * $htmlOptions['template']&nbsp&nbsp&nbsp&nbsp&nbsp= '{input} {label}';</br>
     * $htmlOptions['separator']&nbsp&nbsp&nbsp&nbsp= '&nbsp&nbsp';</br>
     * </code>
     * You can also override them by passing your
     * own configurations in the params.
     * default $data
     * @param CModel $model
     * @param string $attribute
     * @param array $data
     * @param array $htmlOptions 
     */
    public function yesNoRadioButtonList($model, $attribute, $data = array(), $htmlOptions = array())
    {
        if(empty($data)) 
            $data = array('1'=>'Yes','0'=>'No');

        $labelOptions = array('style' => 'display:inline');
        if(!isset($htmlOptions['template']))
            $htmlOptions['template']     = '{input} {label}';
        if(!isset($htmlOptions['separator']))
            $htmlOptions['separator']    = '&nbsp&nbsp';
        if(isset($htmlOptions['labelOptions']))
            $htmlOptions['labelOptions'] = array_merge($htmlOptions['labelOptions'], $labelOptions);
        else
            $htmlOptions['labelOptions'] = $labelOptions;
        return $this->radioButtonList($model, $attribute, $data, $htmlOptions);
    }
    
    /**
     * This method simply calls the widget CMaskedTextField. </br>
     * $model and $attribute will go into the options 'model' and 'attribute' of the options array.</br>
     * Any declaration of 'model' and 'attribute' in $options will overwrite the specified $model and $attribute.
     * @param CModel $model
     * @param string $attribute
     * @param array $options 
     */
    public function maskedTextField($model, $attribute, $options = array())
    {
        if(!isset($options['model']))
            $options['model']     = $model;
        if(!isset($options['attribute']))
            $options['attribute'] = $attribute;
        ob_start();
        Yii::app()->controller->widget('CMaskedTextField', $options);
        $maskedTextField = ob_get_contents();
        ob_end_clean();
        return $maskedTextField;
    }
}

?>
